home *** CD-ROM | disk | FTP | other *** search
/ TeX 1995 July / TeX CD-ROM July 1995 (Disc 1)(Walnut Creek)(1995).ISO / graphics / tiff / libtiff / tif_getimage.c < prev    next >
C/C++ Source or Header  |  1992-03-10  |  27KB  |  1,151 lines

  1. #ifndef lint
  2. static char rcsid[] = "$Header: /usr/people/sam/tiff/libtiff/RCS/tif_getimage.c,v 1.8 92/03/11 09:19:10 sam Exp $";
  3. #endif
  4.  
  5. /*
  6.  * Copyright (c) 1991, 1992 Sam Leffler
  7.  * Copyright (c) 1991, 1992 Silicon Graphics, Inc.
  8.  *
  9.  * Permission to use, copy, modify, distribute, and sell this software and 
  10.  * its documentation for any purpose is hereby granted without fee, provided
  11.  * that (i) the above copyright notices and this permission notice appear in
  12.  * all copies of the software and related documentation, and (ii) the names of
  13.  * Sam Leffler and Silicon Graphics may not be used in any advertising or
  14.  * publicity relating to the software without the specific, prior written
  15.  * permission of Sam Leffler and Silicon Graphics.
  16.  * 
  17.  * THE SOFTWARE IS PROVIDED "AS-IS" AND WITHOUT WARRANTY OF ANY KIND, 
  18.  * EXPRESS, IMPLIED OR OTHERWISE, INCLUDING WITHOUT LIMITATION, ANY 
  19.  * WARRANTY OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE.  
  20.  * 
  21.  * IN NO EVENT SHALL SAM LEFFLER OR SILICON GRAPHICS BE LIABLE FOR
  22.  * ANY SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND,
  23.  * OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
  24.  * WHETHER OR NOT ADVISED OF THE POSSIBILITY OF DAMAGE, AND ON ANY THEORY OF 
  25.  * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE 
  26.  * OF THIS SOFTWARE.
  27.  */
  28.  
  29. /*
  30.  * TIFF Library
  31.  *
  32.  * Read and return a packed RGBA image.
  33.  */
  34. #include "tiffio.h"
  35. #include "tiffcompat.h"
  36. #include "prototypes.h"
  37.  
  38. typedef    u_char RGBvalue;
  39.  
  40. static    u_long width, height;        /* image width & height */
  41. static    u_short bitspersample;
  42. static    u_short samplesperpixel;
  43. static    u_short photometric;
  44. static    u_short orientation;
  45. /* colormap for pallete images */
  46. static    u_short *redcmap, *greencmap, *bluecmap;
  47. static    int stoponerr;            /* stop on read error */
  48. static    char *filename;
  49. /* YCbCr support */
  50. static    u_short YCbCrHorizSampling;
  51. static    u_short YCbCrVertSampling;
  52. static    float *YCbCrCoeffs;
  53. static    float *refBlackWhite;
  54.  
  55. static    u_long **BWmap;
  56. static    u_long **PALmap;
  57.  
  58. static    int gt();
  59.  
  60. TIFFReadRGBAImage(tif, rwidth, rheight, raster, stop)
  61.     TIFF *tif;
  62.     u_long rwidth, rheight;
  63.     u_long *raster;
  64.     int stop;
  65. {
  66.     int ok;
  67.     u_long width, height;
  68.  
  69.     TIFFGetFieldDefaulted(tif, TIFFTAG_BITSPERSAMPLE, &bitspersample);
  70.     switch (bitspersample) {
  71.     case 1: case 2: case 4:
  72.     case 8: case 16:
  73.         break;
  74.     default:
  75.         TIFFError(TIFFFileName(tif),
  76.             "Sorry, can not handle %d-bit pictures", bitspersample);
  77.         return (0);
  78.     }
  79.     TIFFGetFieldDefaulted(tif, TIFFTAG_SAMPLESPERPIXEL, &samplesperpixel);
  80.     switch (samplesperpixel) {
  81.     case 1: case 3: case 4:
  82.         break;
  83.     default:
  84.         TIFFError(TIFFFileName(tif),
  85.             "Sorry, can not handle %d-channel images", samplesperpixel);
  86.         return (0);
  87.     }
  88.     if (!TIFFGetField(tif, TIFFTAG_PHOTOMETRIC, &photometric)) {
  89.         switch (samplesperpixel) {
  90.         case 1:
  91.             photometric = PHOTOMETRIC_MINISBLACK;
  92.             break;
  93.         case 3: case 4:
  94.             photometric = PHOTOMETRIC_RGB;
  95.             break;
  96.         default:
  97.             TIFFError(TIFFFileName(tif),
  98.                 "Missing needed \"PhotometricInterpretation\" tag");
  99.             return (0);
  100.         }
  101.         TIFFError(TIFFFileName(tif),
  102.             "No \"PhotometricInterpretation\" tag, assuming %s\n",
  103.             photometric == PHOTOMETRIC_RGB ? "RGB" : "min-is-black");
  104.     }
  105.     /* XXX maybe should check photometric? */
  106.     TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &width);
  107.     TIFFGetField(tif, TIFFTAG_IMAGELENGTH, &height);
  108.     /* XXX verify rwidth and rheight against width and height */
  109.     stoponerr = stop;
  110.     BWmap = NULL;
  111.     PALmap = NULL;
  112.     ok = gt(tif, rwidth, height, raster + (rheight-height)*rwidth);
  113.     if (BWmap)
  114.         free((char *)BWmap);
  115.     if (PALmap)
  116.         free((char *)PALmap);
  117.     return (ok);
  118. }
  119.  
  120. static int
  121. checkcmap(n, r, g, b)
  122.     int n;
  123.     u_short *r, *g, *b;
  124. {
  125.     while (n-- > 0)
  126.         if (*r++ >= 256 || *g++ >= 256 || *b++ >= 256)
  127.             return (16);
  128.     TIFFWarning(filename, "Assuming 8-bit colormap");
  129.     return (8);
  130. }
  131.  
  132. static    gtTileContig();
  133. static    gtTileSeparate();
  134. static    gtStripContig();
  135. static    gtStripSeparate();
  136. static    void initYCbCrConversion();
  137.  
  138. static
  139. gt(tif, w, h, raster)
  140.     TIFF *tif;
  141.     int w, h;
  142.     u_long *raster;
  143. {
  144.     u_short minsamplevalue, maxsamplevalue, planarconfig;
  145.     RGBvalue *Map;
  146.     int e;
  147.  
  148.     TIFFGetFieldDefaulted(tif, TIFFTAG_MINSAMPLEVALUE, &minsamplevalue);
  149.     TIFFGetFieldDefaulted(tif, TIFFTAG_MAXSAMPLEVALUE, &maxsamplevalue);
  150.     Map = NULL;
  151.     switch (photometric) {
  152.     case PHOTOMETRIC_YCBCR:
  153.         TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRCOEFFICIENTS,
  154.             &YCbCrCoeffs);
  155.         TIFFGetFieldDefaulted(tif, TIFFTAG_YCBCRSUBSAMPLING,
  156.             &YCbCrHorizSampling, &YCbCrVertSampling);
  157.         TIFFGetFieldDefaulted(tif, TIFFTAG_REFERENCEBLACKWHITE,
  158.             &refBlackWhite);
  159.         initYCbCrConversion();
  160.         /* fall thru... */
  161.     case PHOTOMETRIC_RGB:
  162.         if (minsamplevalue == 0 && maxsamplevalue == 255)
  163.             break;
  164.         /* fall thru... */
  165.     case PHOTOMETRIC_MINISBLACK:
  166.     case PHOTOMETRIC_MINISWHITE: {
  167.         register int x, range;
  168.  
  169.         range = maxsamplevalue - minsamplevalue;
  170.         Map = (RGBvalue *)malloc((range + 1) * sizeof (RGBvalue));
  171.         if (Map == NULL) {
  172.             TIFFError(filename,
  173.                 "No space for photometric conversion table");
  174.             return (0);
  175.         }
  176.         if (photometric == PHOTOMETRIC_MINISWHITE) {
  177.             for (x = 0; x <= range; x++)
  178.             Map[x] = ((range - x) * 255) / range;
  179.         } else {
  180.             for (x = 0; x <= range; x++)
  181.             Map[x] = (x * 255) / range;
  182.         }
  183.         if (photometric != PHOTOMETRIC_RGB && bitspersample <= 8) {
  184.             /*
  185.              * Use photometric mapping table to construct
  186.              * unpacking tables for samples <= 8 bits.
  187.              */
  188.             if (!makebwmap(Map))
  189.                 return (0);
  190.             /* no longer need Map, free it */
  191.             free((char *)Map);
  192.             Map = NULL;
  193.         }
  194.         break;
  195.     }
  196.     case PHOTOMETRIC_PALETTE:
  197.         if (!TIFFGetField(tif, TIFFTAG_COLORMAP,
  198.                   &redcmap, &greencmap, &bluecmap)) {
  199.             TIFFError(filename,
  200.                 "Missing required \"Colormap\" tag");
  201.             return (0);
  202.         }
  203.         /*
  204.          * Convert 16-bit colormap to 8-bit (unless it looks
  205.          * like an old-style 8-bit colormap).
  206.          */
  207.         if (checkcmap(1<<bitspersample, redcmap, greencmap, bluecmap) == 16) {
  208.             int i;
  209.             for (i = (1<<bitspersample)-1; i > 0; i--) {
  210. #define    CVT(x)        (((x) * 255) / ((1L<<16)-1))
  211.                 redcmap[i] = CVT(redcmap[i]);
  212.                 greencmap[i] = CVT(greencmap[i]);
  213.                 bluecmap[i] = CVT(bluecmap[i]);
  214.             }
  215.         }
  216.         if (bitspersample <= 8) {
  217.             /*
  218.              * Use mapping table and colormap to construct
  219.              * unpacking tables for samples < 8 bits.
  220.              */
  221.             if (!makecmap(redcmap, greencmap, bluecmap))
  222.                 return (0);
  223.         }
  224.         break;
  225.     }
  226.     TIFFGetField(tif, TIFFTAG_PLANARCONFIG, &planarconfig);
  227.     if (planarconfig == PLANARCONFIG_SEPARATE && samplesperpixel > 1) {
  228.         e = TIFFIsTiled(tif) ?
  229.             gtTileSeparate(tif, raster, Map, h, w) :
  230.             gtStripSeparate(tif, raster, Map, h, w);
  231.     } else {
  232.         e = TIFFIsTiled(tif) ? 
  233.             gtTileContig(tif, raster, Map, h, w) :
  234.             gtStripContig(tif, raster, Map, h, w);
  235.     }
  236.     if (Map)
  237.         free((char *)Map);
  238.     return (e);
  239. }
  240.  
  241. u_long
  242. setorientation(tif, h)
  243.     TIFF *tif;
  244.     u_long h;
  245. {
  246.     u_long y;
  247.  
  248.     TIFFGetFieldDefaulted(tif, TIFFTAG_ORIENTATION, &orientation);
  249.     switch (orientation) {
  250.     case ORIENTATION_BOTRIGHT:
  251.     case ORIENTATION_RIGHTBOT:    /* XXX */
  252.     case ORIENTATION_LEFTBOT:    /* XXX */
  253.         TIFFWarning(filename, "using bottom-left orientation");
  254.         orientation = ORIENTATION_BOTLEFT;
  255.         /* fall thru... */
  256.     case ORIENTATION_BOTLEFT:
  257.         y = 0;
  258.         break;
  259.     case ORIENTATION_TOPRIGHT:
  260.     case ORIENTATION_RIGHTTOP:    /* XXX */
  261.     case ORIENTATION_LEFTTOP:    /* XXX */
  262.     default:
  263.         TIFFWarning(filename, "using top-left orientation");
  264.         orientation = ORIENTATION_TOPLEFT;
  265.         /* fall thru... */
  266.     case ORIENTATION_TOPLEFT:
  267.         y = h-1;
  268.         break;
  269.     }
  270.     return (y);
  271. }
  272.  
  273. #if USE_PROTOTYPES
  274. typedef void (*tileContigRoutine)
  275.     (u_long*, u_char*, RGBvalue*, u_long, u_long, int, int);
  276. static tileContigRoutine pickTileContigCase(RGBvalue*);
  277. #else
  278. typedef void (*tileContigRoutine)();
  279. static tileContigRoutine pickTileContigCase();
  280. #endif
  281.  
  282. /*
  283.  * Get an tile-organized image that has
  284.  *    PlanarConfiguration contiguous if SamplesPerPixel > 1
  285.  * or
  286.  *    SamplesPerPixel == 1
  287.  */    
  288. static
  289. gtTileContig(tif, raster, Map, h, w)
  290.     TIFF *tif;
  291.     u_long *raster;
  292.     RGBvalue *Map;
  293.     u_long h, w;
  294. {
  295.     u_long col, row, y;
  296.     u_long tw, th;
  297.     u_char *buf;
  298.     int fromskew, toskew;
  299.     u_int nrow;
  300.     tileContigRoutine put;
  301.  
  302.     put = pickTileContigCase(Map);
  303.     if (put == 0)
  304.         return (0);
  305.     buf = (u_char *)malloc(TIFFTileSize(tif));
  306.     if (buf == 0) {
  307.         TIFFError(filename, "No space for tile buffer");
  308.         return (0);
  309.     }
  310.     TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw);
  311.     TIFFGetField(tif, TIFFTAG_TILELENGTH, &th);
  312.     y = setorientation(tif, h);
  313.     toskew = (orientation == ORIENTATION_TOPLEFT ? -tw + -w : -tw + w);
  314.     for (row = 0; row < h; row += th) {
  315.         nrow = (row + th > h ? h - row : th);
  316.         for (col = 0; col < w; col += tw) {
  317.             if (TIFFReadTile(tif, buf, col, row, 0, 0) < 0 &&
  318.                 stoponerr)
  319.                 break;
  320.             if (col + tw > w) {
  321.                 /*
  322.                  * Tile is clipped horizontally.  Calculate
  323.                  * visible portion and skewing factors.
  324.                  */
  325.                 u_long npix = w - col;
  326.                 fromskew = tw - npix;
  327.                 (*put)(raster + y*w + col, buf, Map,
  328.                     npix, nrow, fromskew, toskew + fromskew);
  329.             } else
  330.                 (*put)(raster + y*w + col, buf, Map,
  331.                     tw, nrow, 0, toskew);
  332.         }
  333.         y += (orientation == ORIENTATION_TOPLEFT ? -nrow : nrow);
  334.     }
  335.     free(buf);
  336.     return (1);
  337. }
  338.  
  339. #if USE_PROTOTYPES
  340. typedef void (*tileSeparateRoutine)
  341.     (u_long*, u_char*, u_char*, u_char*, RGBvalue*, u_long, u_long, int, int);
  342. static tileSeparateRoutine pickTileSeparateCase(RGBvalue*);
  343. #else
  344. typedef void (*tileSeparateRoutine)();
  345. static tileSeparateRoutine pickTileSeparateCase();
  346. #endif
  347.  
  348. /*
  349.  * Get an tile-organized image that has
  350.  *     SamplesPerPixel > 1
  351.  *     PlanarConfiguration separated
  352.  * We assume that all such images are RGB.
  353.  */    
  354. static
  355. gtTileSeparate(tif, raster, Map, h, w)
  356.     TIFF *tif;
  357.     u_long *raster;
  358.     RGBvalue *Map;
  359.     u_long h, w;
  360. {
  361.     u_long col, row, y;
  362.     u_long tw, th;
  363.     u_char *buf;
  364.     u_char *r, *g, *b;
  365.     int tilesize;
  366.     int fromskew, toskew;
  367.     u_int nrow;
  368.     tileSeparateRoutine put;
  369.  
  370.     put = pickTileSeparateCase(Map);
  371.     if (put == 0)
  372.         return (0);
  373.     tilesize = TIFFTileSize(tif);
  374.     buf = (u_char *)malloc(3*tilesize);
  375.     if (buf == 0) {
  376.         TIFFError(filename, "No space for tile buffer");
  377.         return (0);
  378.     }
  379.     r = buf;
  380.     g = r + tilesize;
  381.     b = g + tilesize;
  382.     TIFFGetField(tif, TIFFTAG_TILEWIDTH, &tw);
  383.     TIFFGetField(tif, TIFFTAG_TILELENGTH, &th);
  384.     y = setorientation(tif, h);
  385.     toskew = (orientation == ORIENTATION_TOPLEFT ? -tw + -w : -tw + w);
  386.     for (row = 0; row < h; row += th) {
  387.         nrow = (row + th > h ? h - row : th);
  388.         for (col = 0; col < w; col += tw) {
  389.             if (TIFFReadTile(tif, r, col, row,0,0) < 0 && stoponerr)
  390.                 break;
  391.             if (TIFFReadTile(tif, g, col, row,0,1) < 0 && stoponerr)
  392.                 break;
  393.             if (TIFFReadTile(tif, b, col, row,0,2) < 0 && stoponerr)
  394.                 break;
  395.             if (col + tw > w) {
  396.                 /*
  397.                  * Tile is clipped horizontally.  Calculate
  398.                  * visible portion and skewing factors.
  399.                  */
  400.                 u_long npix = w - col;
  401.                 fromskew = tw - npix;
  402.                 (*put)(raster + y*w + col, r, g, b, Map,
  403.                     npix, nrow, fromskew, toskew + fromskew);
  404.             } else
  405.                 (*put)(raster + y*w + col, r, g, b, Map,
  406.                     tw, nrow, 0, toskew);
  407.         }
  408.         y += (orientation == ORIENTATION_TOPLEFT ? -nrow : nrow);
  409.     }
  410.     free(buf);
  411.     return (1);
  412. }
  413.  
  414. /*
  415.  * Get a strip-organized image that has
  416.  *    PlanarConfiguration contiguous if SamplesPerPixel > 1
  417.  * or
  418.  *    SamplesPerPixel == 1
  419.  */    
  420. static
  421. gtStripContig(tif, raster, Map, h, w)
  422.     TIFF *tif;
  423.     u_long *raster;
  424.     RGBvalue *Map;
  425.     u_long h, w;
  426. {
  427.     u_long row, y, nrow;
  428.     u_char *buf;
  429.     tileContigRoutine put;
  430.     u_long rowsperstrip;
  431.     u_long imagewidth;
  432.     int scanline;
  433.     int fromskew, toskew;
  434.  
  435.     put = pickTileContigCase(Map);
  436.     if (put == 0)
  437.         return (0);
  438.     buf = (u_char *)malloc(TIFFStripSize(tif));
  439.     if (buf == 0) {
  440.         TIFFError(filename, "No space for strip buffer");
  441.         return (0);
  442.     }
  443.     y = setorientation(tif, h);
  444.     toskew = (orientation == ORIENTATION_TOPLEFT ? -w + -w : -w + w);
  445.     TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
  446.     TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &imagewidth);
  447.     scanline = TIFFScanlineSize(tif);
  448.     fromskew = (w < imagewidth ? imagewidth - w : 0);
  449.     for (row = 0; row < h; row += rowsperstrip) {
  450.         nrow = (row + rowsperstrip > h ? h - row : rowsperstrip);
  451.         if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 0),
  452.             buf, nrow*scanline) < 0 && stoponerr)
  453.             break;
  454.         (*put)(raster + y*w, buf, Map, w, nrow, fromskew, toskew);
  455.         y += (orientation == ORIENTATION_TOPLEFT ? -nrow : nrow);
  456.     }
  457.     free(buf);
  458.     return (1);
  459. }
  460.  
  461. /*
  462.  * Get a strip-organized image with
  463.  *     SamplesPerPixel > 1
  464.  *     PlanarConfiguration separated
  465.  * We assume that all such images are RGB.
  466.  */
  467. static
  468. gtStripSeparate(tif, raster, Map, h, w)
  469.     TIFF *tif;
  470.     u_long *raster;
  471.     register RGBvalue *Map;
  472.     u_long h, w;
  473. {
  474.     u_char *buf;
  475.     u_char *r, *g, *b;
  476.     u_long row, y, nrow;
  477.     int scanline;
  478.     tileSeparateRoutine put;
  479.     u_long rowsperstrip;
  480.     u_long imagewidth;
  481.     u_int stripsize;
  482.     int fromskew, toskew;
  483.  
  484.     stripsize = TIFFStripSize(tif);
  485.     r = buf = (u_char *)malloc(3*stripsize);
  486.     if (buf == 0)
  487.         return (0);
  488.     g = r + stripsize;
  489.     b = g + stripsize;
  490.     put = pickTileSeparateCase(Map);
  491.     if (put == 0) {
  492.         TIFFError(filename, "Can not handle format");
  493.         return (0);
  494.     }
  495.     y = setorientation(tif, h);
  496.     toskew = (orientation == ORIENTATION_TOPLEFT ? -w + -w : -w + w);
  497.     TIFFGetFieldDefaulted(tif, TIFFTAG_ROWSPERSTRIP, &rowsperstrip);
  498.     TIFFGetField(tif, TIFFTAG_IMAGEWIDTH, &imagewidth);
  499.     scanline = TIFFScanlineSize(tif);
  500.     fromskew = (w < imagewidth ? imagewidth - w : 0);
  501.     for (row = 0; row < h; row += rowsperstrip) {
  502.         nrow = (row + rowsperstrip > h ? h - row : rowsperstrip);
  503.         if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 0),
  504.             r, nrow*scanline) < 0 && stoponerr)
  505.             break;
  506.         if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 1),
  507.             g, nrow*scanline) < 0 && stoponerr)
  508.             break;
  509.         if (TIFFReadEncodedStrip(tif, TIFFComputeStrip(tif, row, 2),
  510.             b, nrow*scanline) < 0 && stoponerr)
  511.             break;
  512.         (*put)(raster + y*w, r, g, b, Map, w, nrow, fromskew, toskew);
  513.         y += (orientation == ORIENTATION_TOPLEFT ? -nrow : nrow);
  514.     }
  515.     free(buf);
  516.     return (1);
  517. }
  518.  
  519. #define    PACK(r,g,b)    ((u_long)(r)|((u_long)(g)<<8)|((u_long)(b)<<16))
  520.  
  521. /*
  522.  * Greyscale images with less than 8 bits/sample are handled
  523.  * with a table to avoid lots of shifts and masks.  The table
  524.  * is setup so that put*bwtile (below) can retrieve 8/bitspersample
  525.  * pixel values simply by indexing into the table with one
  526.  * number.
  527.  */
  528. makebwmap(Map)
  529.     RGBvalue *Map;
  530. {
  531.     register int i;
  532.     int nsamples = 8 / bitspersample;
  533.     register u_long *p;
  534.  
  535.     BWmap = (u_long **)malloc(
  536.         256*sizeof (u_long *)+(256*nsamples*sizeof(u_long)));
  537.     if (BWmap == NULL) {
  538.         TIFFError(filename, "No space for B&W mapping table");
  539.         return (0);
  540.     }
  541.     p = (u_long *)(BWmap + 256);
  542.     for (i = 0; i < 256; i++) {
  543.         BWmap[i] = p;
  544.         switch (bitspersample) {
  545.             register RGBvalue c;
  546. #define    GREY(x)    c = Map[x]; *p++ = PACK(c,c,c);
  547.         case 1:
  548.             GREY(i>>7);
  549.             GREY((i>>6)&1);
  550.             GREY((i>>5)&1);
  551.             GREY((i>>4)&1);
  552.             GREY((i>>3)&1);
  553.             GREY((i>>2)&1);
  554.             GREY((i>>1)&1);
  555.             GREY(i&1);
  556.             break;
  557.         case 2:
  558.             GREY(i>>6);
  559.             GREY((i>>4)&3);
  560.             GREY((i>>2)&3);
  561.             GREY(i&3);
  562.             break;
  563.         case 4:
  564.             GREY(i>>4);
  565.             GREY(i&0xf);
  566.             break;
  567.         case 8:
  568.             GREY(i);
  569.             break;
  570.         }
  571. #undef    GREY
  572.     }
  573.     return (1);
  574. }
  575.  
  576. /*
  577.  * Palette images with <= 8 bits/sample are handled
  578.  * with a table to avoid lots of shifts and masks.  The table
  579.  * is setup so that put*cmaptile (below) can retrieve 8/bitspersample
  580.  * pixel values simply by indexing into the table with one
  581.  * number.
  582.  */
  583. makecmap(rmap, gmap, bmap)
  584.     u_short *rmap, *gmap, *bmap;
  585. {
  586.     register int i;
  587.     int nsamples = 8 / bitspersample;
  588.     register u_long *p;
  589.  
  590.     PALmap = (u_long **)malloc(
  591.         256*sizeof (u_long *)+(256*nsamples*sizeof(u_long)));
  592.     if (PALmap == NULL) {
  593.         TIFFError(filename, "No space for Palette mapping table");
  594.         return (0);
  595.     }
  596.     p = (u_long *)(PALmap + 256);
  597.     for (i = 0; i < 256; i++) {
  598.         PALmap[i] = p;
  599. #define    CMAP(x)    \
  600. c = x; *p++ = PACK(rmap[c]&0xff, gmap[c]&0xff, bmap[c]&0xff);
  601.         switch (bitspersample) {
  602.             register RGBvalue c;
  603.         case 1:
  604.             CMAP(i>>7);
  605.             CMAP((i>>6)&1);
  606.             CMAP((i>>5)&1);
  607.             CMAP((i>>4)&1);
  608.             CMAP((i>>3)&1);
  609.             CMAP((i>>2)&1);
  610.             CMAP((i>>1)&1);
  611.             CMAP(i&1);
  612.             break;
  613.         case 2:
  614.             CMAP(i>>6);
  615.             CMAP((i>>4)&3);
  616.             CMAP((i>>2)&3);
  617.             CMAP(i&3);
  618.             break;
  619.         case 4:
  620.             CMAP(i>>4);
  621.             CMAP(i&0xf);
  622.             break;
  623.         case 8:
  624.             CMAP(i);
  625.             break;
  626.         }
  627. #undef CMAP
  628.     }
  629.     return (1);
  630. }
  631.  
  632. /*
  633.  * The following routines move decoded data returned
  634.  * from the TIFF library into rasters filled with packed
  635.  * ABGR pixels (i.e. suitable for passing to lrecwrite.)
  636.  *
  637.  * The routines have been created according to the most
  638.  * important cases and optimized.  pickTileContigCase and
  639.  * pickTileSeparateCase analyze the parameters and select
  640.  * the appropriate "put" routine to use.
  641.  */
  642. #define    REPEAT8(op)    REPEAT4(op); REPEAT4(op)
  643. #define    REPEAT4(op)    REPEAT2(op); REPEAT2(op)
  644. #define    REPEAT2(op)    op; op
  645. #define    CASE8(x,op)                \
  646.     switch (x) {                \
  647.     case 7: op; case 6: op; case 5: op;    \
  648.     case 4: op; case 3: op; case 2: op;    \
  649.     case 1: op;                \
  650.     }
  651. #define    CASE4(x,op)    switch (x) { case 3: op; case 2: op; case 1: op; }
  652.  
  653. #define    UNROLL8(w, op1, op2) {        \
  654.     register u_long x;        \
  655.     for (x = w; x >= 8; x -= 8) {    \
  656.         op1;            \
  657.         REPEAT8(op2);        \
  658.     }                \
  659.     if (x > 0) {            \
  660.         op1;            \
  661.         CASE8(x,op2);        \
  662.     }                \
  663. }
  664. #define    UNROLL4(w, op1, op2) {        \
  665.     register u_long x;        \
  666.     for (x = w; x >= 4; x -= 4) {    \
  667.         op1;            \
  668.         REPEAT4(op2);        \
  669.     }                \
  670.     if (x > 0) {            \
  671.         op1;            \
  672.         CASE4(x,op2);        \
  673.     }                \
  674. }
  675. #define    UNROLL2(w, op1, op2) {        \
  676.     register u_long x;        \
  677.     for (x = w; x >= 2; x -= 2) {    \
  678.         op1;            \
  679.         REPEAT2(op2);        \
  680.     }                \
  681.     if (x) {            \
  682.         op1;            \
  683.         op2;            \
  684.     }                \
  685. }
  686.             
  687.  
  688. #define    SKEW(r,g,b,skew)    { r += skew; g += skew; b += skew; }
  689.  
  690. /*
  691.  * 8-bit palette => colormap/RGB
  692.  */
  693. static void
  694. put8bitcmaptile(cp, pp, Map, w, h, fromskew, toskew)
  695.     register u_long *cp;
  696.     register u_char *pp;
  697.     RGBvalue *Map;
  698.     u_long w, h;
  699.     int fromskew, toskew;
  700. {
  701.     while (h-- > 0) {
  702.         UNROLL8(w,, *cp++ = PALmap[*pp++][0]);
  703.         cp += toskew;
  704.         pp += fromskew;
  705.     }
  706. }
  707.  
  708. /*
  709.  * 4-bit palette => colormap/RGB
  710.  */
  711. static void
  712. put4bitcmaptile(cp, pp, Map, w, h, fromskew, toskew)
  713.     register u_long *cp;
  714.     register u_char *pp;
  715.     register RGBvalue *Map;
  716.     u_long w, h;
  717.     int fromskew, toskew;
  718. {
  719.     register u_long *bw;
  720.  
  721.     fromskew /= 2;
  722.     while (h-- > 0) {
  723.         UNROLL2(w, bw = PALmap[*pp++], *cp++ = *bw++);
  724.         cp += toskew;
  725.         pp += fromskew;
  726.     }
  727. }
  728.  
  729. /*
  730.  * 2-bit palette => colormap/RGB
  731.  */
  732. static void
  733. put2bitcmaptile(cp, pp, Map, w, h, fromskew, toskew)
  734.     register u_long *cp;
  735.     register u_char *pp;
  736.     register RGBvalue *Map;
  737.     u_long w, h;
  738.     int fromskew, toskew;
  739. {
  740.     register u_long *bw;
  741.  
  742.     fromskew /= 4;
  743.     while (h-- > 0) {
  744.         UNROLL4(w, bw = PALmap[*pp++], *cp++ = *bw++);
  745.         cp += toskew;
  746.         pp += fromskew;
  747.     }
  748. }
  749.  
  750. /*
  751.  * 1-bit palette => colormap/RGB
  752.  */
  753. static void
  754. put1bitcmaptile(cp, pp, Map, w, h, fromskew, toskew)
  755.     register u_long *cp;
  756.     register u_char *pp;
  757.     register RGBvalue *Map;
  758.     u_long w, h;
  759.     int fromskew, toskew;
  760. {
  761.     register u_long *bw;
  762.  
  763.     fromskew /= 8;
  764.     while (h-- > 0) {
  765.         UNROLL8(w, bw = PALmap[*pp++], *cp++ = *bw++);
  766.         cp += toskew;
  767.         pp += fromskew;
  768.     }
  769. }
  770.  
  771. /*
  772.  * 8-bit greyscale => colormap/RGB
  773.  */
  774. static void
  775. putgreytile(cp, pp, Map, w, h, fromskew, toskew)
  776.     register u_long *cp;
  777.     register u_char *pp;
  778.     RGBvalue *Map;
  779.     u_long w, h;
  780.     int fromskew, toskew;
  781. {
  782.     while (h-- > 0) {
  783.         register u_long x;
  784.         for (x = w; x-- > 0;)
  785.             *cp++ = BWmap[*pp++][0];
  786.         cp += toskew;
  787.         pp += fromskew;
  788.     }
  789. }
  790.  
  791. /*
  792.  * 1-bit bilevel => colormap/RGB
  793.  */
  794. static void
  795. put1bitbwtile(cp, pp, Map, w, h, fromskew, toskew)
  796.     u_long *cp;
  797.     u_char *pp;
  798.     RGBvalue *Map;
  799.     u_long w, h;
  800.     int fromskew, toskew;
  801. {
  802.     register u_long *bw;
  803.  
  804.     fromskew /= 8;
  805.     while (h-- > 0) {
  806.         UNROLL8(w, bw = BWmap[*pp++], *cp++ = *bw++);
  807.         cp += toskew;
  808.         pp += fromskew;
  809.     }
  810. }
  811.  
  812. /*
  813.  * 2-bit greyscale => colormap/RGB
  814.  */
  815. static void
  816. put2bitbwtile(cp, pp, Map, w, h, fromskew, toskew)
  817.     u_long *cp;
  818.     u_char *pp;
  819.     RGBvalue *Map;
  820.     u_long w, h;
  821.     int fromskew, toskew;
  822. {
  823.     register u_long *bw;
  824.  
  825.     fromskew /= 4;
  826.     while (h-- > 0) {
  827.         UNROLL4(w, bw = BWmap[*pp++], *cp++ = *bw++);
  828.         cp += toskew;
  829.         pp += fromskew;
  830.     }
  831. }
  832.  
  833. /*
  834.  * 4-bit greyscale => colormap/RGB
  835.  */
  836. static void
  837. put4bitbwtile(cp, pp, Map, w, h, fromskew, toskew)
  838.     u_long *cp;
  839.     u_char *pp;
  840.     RGBvalue *Map;
  841.     u_long w, h;
  842.     int fromskew, toskew;
  843. {
  844.     register u_long *bw;
  845.  
  846.     fromskew /= 2;
  847.     while (h-- > 0) {
  848.         UNROLL2(w, bw = BWmap[*pp++], *cp++ = *bw++);
  849.         cp += toskew;
  850.         pp += fromskew;
  851.     }
  852. }
  853.  
  854. /*
  855.  * 8-bit packed samples => RGB
  856.  */
  857. static void
  858. putRGBcontig8bittile(cp, pp, Map, w, h, fromskew, toskew)
  859.     register u_long *cp;
  860.     register u_char *pp;
  861.     register RGBvalue *Map;
  862.     u_long w, h;
  863.     int fromskew, toskew;
  864. {
  865.     fromskew *= samplesperpixel;
  866.     if (Map) {
  867.         while (h-- > 0) {
  868.             register u_long x;
  869.             for (x = w; x-- > 0;) {
  870.                 *cp++ = PACK(Map[pp[0]], Map[pp[1]], Map[pp[2]]);
  871.                 pp += samplesperpixel;
  872.             }
  873.             pp += fromskew;
  874.             cp += toskew;
  875.         }
  876.     } else {
  877.         while (h-- > 0) {
  878.             UNROLL8(w,,
  879.                 *cp++ = PACK(pp[0], pp[1], pp[2]);
  880.                 pp += samplesperpixel);
  881.             cp += toskew;
  882.             pp += fromskew;
  883.         }
  884.     }
  885. }
  886.  
  887. /*
  888.  * 16-bit packed samples => RGB
  889.  */
  890. static void
  891. putRGBcontig16bittile(cp, pp, Map, w, h, fromskew, toskew)
  892.     register u_long *cp;
  893.     u_char *pp;
  894.     register RGBvalue *Map;
  895.     u_long w, h;
  896.     int fromskew, toskew;
  897. {
  898.     register u_short *wp = (u_short *)pp;
  899.     register u_int x;
  900.  
  901.     fromskew *= samplesperpixel;
  902.     if (Map) {
  903.         while (h-- > 0) {
  904.             for (x = w; x-- > 0;) {
  905.                 *cp++ = PACK(Map[wp[0]], Map[wp[1]], Map[wp[2]]);
  906.                 wp += samplesperpixel;
  907.             }
  908.             cp += toskew;
  909.             wp += fromskew;
  910.         }
  911.     } else {
  912.         while (h-- > 0) {
  913.             for (x = w; x-- > 0;) {
  914.                 *cp++ = PACK(wp[0], wp[1], wp[2]);
  915.                 wp += samplesperpixel;
  916.             }
  917.             cp += toskew;
  918.             wp += fromskew;
  919.         }
  920.     }
  921. }
  922.  
  923. /*
  924.  * 8-bit unpacked samples => RGB
  925.  */
  926. static void
  927. putRGBseparate8bittile(cp, r, g, b, Map, w, h, fromskew, toskew)
  928.     register u_long *cp;
  929.     register u_char *r, *g, *b;
  930.     register RGBvalue *Map;
  931.     u_long w, h;
  932.     int fromskew, toskew;
  933.  
  934. {
  935.     if (Map) {
  936.         while (h-- > 0) {
  937.             register u_long x;
  938.             for (x = w; x > 0; x--)
  939.                 *cp++ = PACK(Map[*r++], Map[*g++], Map[*b++]);
  940.             SKEW(r, g, b, fromskew);
  941.             cp += toskew;
  942.         }
  943.     } else {
  944.         while (h-- > 0) {
  945.             UNROLL8(w,, *cp++ = PACK(*r++, *g++, *b++));
  946.             SKEW(r, g, b, fromskew);
  947.             cp += toskew;
  948.         }
  949.     }
  950. }
  951.  
  952. /*
  953.  * 16-bit unpacked samples => RGB
  954.  */
  955. static void
  956. putRGBseparate16bittile(cp, br, bg, bb, Map, w, h, fromskew, toskew)
  957.     register u_long *cp;
  958.     u_char *br, *bg, *bb;
  959.     register RGBvalue *Map;
  960.     u_long w, h;
  961.     int fromskew, toskew;
  962. {
  963.     register u_short *r = (u_short *)br;
  964.     register u_short *g = (u_short *)bg;
  965.     register u_short *b = (u_short *)bb;
  966.     register u_long x;
  967.  
  968.     if (Map) {
  969.         while (h-- > 0) {
  970.             for (x = w; x > 0; x--)
  971.                 *cp++ = PACK(Map[*r++], Map[*g++], Map[*b++]);
  972.             SKEW(r, g, b, fromskew);
  973.             cp += toskew;
  974.         }
  975.     } else {
  976.         while (h-- > 0) {
  977.             for (x = 0; x < w; x++)
  978.                 *cp++ = PACK(*r++, *g++, *b++);
  979.             SKEW(r, g, b, fromskew);
  980.             cp += toskew;
  981.         }
  982.     }
  983. }
  984.  
  985. #define    Code2V(c, RB, RW, CR)    ((((c)-RB)*(float)CR)/(float)(RW-RB))
  986. #define    CLAMP(f,min,max) \
  987.     (int)((f)+.5 < (min) ? (min) : (f)+.5 > (max) ? (max) : (f)+.5)
  988.  
  989. #define    LumaRed        YCbCrCoeffs[0]
  990. #define    LumaGreen    YCbCrCoeffs[1]
  991. #define    LumaBlue    YCbCrCoeffs[2]
  992.  
  993. static    float D1, D2;
  994. static    float D3, D4;
  995.  
  996. static void
  997. initYCbCrConversion()
  998. {
  999.     D1 = 2 - 2*LumaRed;
  1000.     D2 = D1*LumaRed / LumaGreen;
  1001.     D3 = 2 - 2*LumaBlue;
  1002.     D4 = D2*LumaBlue / LumaGreen;
  1003. }
  1004.  
  1005. static void
  1006. putRGBContigYCbCrClump(cp, pp, cw, ch, w, n, fromskew, toskew)
  1007.     register u_long *cp;
  1008.     register u_char *pp;
  1009.     int cw, ch;
  1010.     u_long w;
  1011.     int n, fromskew, toskew;
  1012. {
  1013.     float Cb, Cr;
  1014.     int j, k;
  1015.  
  1016.     Cb = Code2V(pp[n],   refBlackWhite[2], refBlackWhite[3], 127);
  1017.     Cr = Code2V(pp[n+1], refBlackWhite[4], refBlackWhite[5], 127);
  1018.     for (j = 0; j < ch; j++) {
  1019.         for (k = 0; k < cw; k++) {
  1020.             float Y, R, G, B;
  1021.             Y = Code2V(*pp++,
  1022.                 refBlackWhite[0], refBlackWhite[1], 255);
  1023.             R = Y + Cr*D1;
  1024.             B = Y + Cb*D3;
  1025.             G = Y - Cb*D4 - Cr*D2;
  1026.             cp[k] = PACK(CLAMP(R,0,255),
  1027.                      CLAMP(G,0,255),
  1028.                      CLAMP(B,0,255));
  1029.         }
  1030.         cp += w+toskew;
  1031.         pp += fromskew;
  1032.     }
  1033. }
  1034. #undef LumaBlue
  1035. #undef LumaGreen
  1036. #undef LumaRed
  1037. #undef CLAMP
  1038. #undef Code2V
  1039.  
  1040. /*
  1041.  * 8-bit packed YCbCr samples => RGB
  1042.  */
  1043. static void
  1044. putcontig8bitYCbCrtile(cp, pp, Map, w, h, fromskew, toskew)
  1045.     register u_long *cp;
  1046.     register u_char *pp;
  1047.     register RGBvalue *Map;
  1048.     u_long w, h;
  1049.     int fromskew, toskew;
  1050. {
  1051.     u_int Coff = YCbCrVertSampling * YCbCrHorizSampling;
  1052.     u_long *tp;
  1053.     u_long x;
  1054.  
  1055.     /* XXX adjust fromskew */
  1056.     while (h >= YCbCrVertSampling) {
  1057.         tp = cp;
  1058.         for (x = w; x >= YCbCrHorizSampling; x -= YCbCrHorizSampling) {
  1059.             putRGBContigYCbCrClump(tp, pp,
  1060.                 YCbCrHorizSampling, YCbCrVertSampling,
  1061.                 w, Coff, 0, toskew);
  1062.             tp += YCbCrHorizSampling;
  1063.             pp += Coff+2;
  1064.         }
  1065.         if (x > 0) {
  1066.             putRGBContigYCbCrClump(tp, pp,
  1067.                 x, YCbCrVertSampling,
  1068.                 w, Coff, YCbCrHorizSampling - x, toskew);
  1069.             pp += Coff+2;
  1070.         }
  1071.         cp += YCbCrVertSampling*(w + toskew);
  1072.         pp += fromskew;
  1073.         h -= YCbCrVertSampling;
  1074.     }
  1075.     if (h > 0) {
  1076.         tp = cp;
  1077.         for (x = w; x >= YCbCrHorizSampling; x -= YCbCrHorizSampling) {
  1078.             putRGBContigYCbCrClump(tp, pp, YCbCrHorizSampling, h,
  1079.                 w, Coff, 0, toskew);
  1080.             tp += YCbCrHorizSampling;
  1081.             pp += Coff+2;
  1082.         }
  1083.         if (x > 0)
  1084.             putRGBContigYCbCrClump(tp, pp, x, h,
  1085.                 w, Coff, YCbCrHorizSampling - x, toskew);
  1086.     }
  1087. }
  1088.  
  1089. /*
  1090.  * Select the appropriate conversion routine for packed data.
  1091.  */
  1092. static tileContigRoutine
  1093. DECLARE1(pickTileContigCase, RGBvalue*, Map)
  1094. {
  1095.     tileContigRoutine put = 0;
  1096.  
  1097.     switch (photometric) {
  1098.     case PHOTOMETRIC_RGB:
  1099.         put = (bitspersample == 8 ?
  1100.             putRGBcontig8bittile : putRGBcontig16bittile);
  1101.         break;
  1102.     case PHOTOMETRIC_PALETTE:
  1103.         switch (bitspersample) {
  1104.         case 8:    put = put8bitcmaptile; break;
  1105.         case 4: put = put4bitcmaptile; break;
  1106.         case 2: put = put2bitcmaptile; break;
  1107.         case 1: put = put1bitcmaptile; break;
  1108.         }
  1109.         break;
  1110.     case PHOTOMETRIC_MINISWHITE:
  1111.     case PHOTOMETRIC_MINISBLACK:
  1112.         switch (bitspersample) {
  1113.         case 8:    put = putgreytile; break;
  1114.         case 4: put = put4bitbwtile; break;
  1115.         case 2: put = put2bitbwtile; break;
  1116.         case 1: put = put1bitbwtile; break;
  1117.         }
  1118.         break;
  1119.     case PHOTOMETRIC_YCBCR:
  1120.         switch (bitspersample) {
  1121.         case 8: put = putcontig8bitYCbCrtile; break;
  1122.         }
  1123.         break;
  1124.     }
  1125.     if (put == 0)
  1126.         TIFFError(filename, "Can not handle format");
  1127.     return (put);
  1128. }
  1129.  
  1130. /*
  1131.  * Select the appropriate conversion routine for unpacked data.
  1132.  *
  1133.  * NB: we assume that unpacked single channel data is directed
  1134.  *     to the "packed routines.
  1135.  */
  1136. static tileSeparateRoutine
  1137. DECLARE1(pickTileSeparateCase, RGBvalue*, Map)
  1138. {
  1139.     tileSeparateRoutine put = 0;
  1140.  
  1141.     switch (photometric) {
  1142.     case PHOTOMETRIC_RGB:
  1143.         put = (bitspersample == 8 ?
  1144.             putRGBseparate8bittile : putRGBseparate16bittile);
  1145.         break;
  1146.     }
  1147.     if (put == 0)
  1148.         TIFFError(filename, "Can not handle format");
  1149.     return (put);
  1150. }
  1151.